﻿Imports System
Imports System.Collections.Generic
Imports System.Drawing

Namespace System.Workflow.ComponentModel.Design
    Friend Class DesignerGeometryHelper
        ' Methods
        Friend Shared Function ClosestEdgeToPoint(ByVal point As Point, ByVal rect As Rectangle, ByVal edgesToConsider As DesignerEdges) As DesignerEdges
            Dim list As New List([Of] Double)
            Dim list2 As New List([Of] DesignerEdges)
            If ((edgesToConsider And DesignerEdges.Left) > DesignerEdges.None) Then
                Dim line As Point() = New Point() { New Point(rect.Left, rect.Top), New Point(rect.Left, rect.Bottom) }
                list.Add(DesignerGeometryHelper.DistanceFromPointToLineSegment(point, line))
                list2.Add(DesignerEdges.Left)
            End If
            If ((edgesToConsider And DesignerEdges.Top) > DesignerEdges.None) Then
                Dim pointArray2 As Point() = New Point() { New Point(rect.Left, rect.Top), New Point(rect.Right, rect.Top) }
                list.Add(DesignerGeometryHelper.DistanceFromPointToLineSegment(point, pointArray2))
                list2.Add(DesignerEdges.Top)
            End If
            If ((edgesToConsider And DesignerEdges.Right) > DesignerEdges.None) Then
                Dim pointArray3 As Point() = New Point() { New Point(rect.Right, rect.Top), New Point(rect.Right, rect.Bottom) }
                list.Add(DesignerGeometryHelper.DistanceFromPointToLineSegment(point, pointArray3))
                list2.Add(DesignerEdges.Right)
            End If
            If ((edgesToConsider And DesignerEdges.Bottom) > DesignerEdges.None) Then
                Dim pointArray4 As Point() = New Point() { New Point(rect.Left, rect.Bottom), New Point(rect.Right, rect.Bottom) }
                list.Add(DesignerGeometryHelper.DistanceFromPointToLineSegment(point, pointArray4))
                list2.Add(DesignerEdges.Bottom)
            End If
            If (list.Count <= 0) Then
                Return DesignerEdges.None
            End If
            Dim num As Double = list.Item(0)
            Dim i As Integer
            For i = 1 To list.Count - 1
                num = Math.Min(num, list.Item(i))
            Next i
            Return list2.Item(list.IndexOf(num))
        End Function

        Friend Shared Function DistanceBetweenPoints(ByVal point1 As Point, ByVal point2 As Point) As Double
            Return Math.Sqrt((Math.Pow(CDbl((point2.X - point1.X)), 2) + Math.Pow(CDbl((point2.Y - point1.Y)), 2)))
        End Function

        Friend Shared Function DistanceFromPointToLineSegment(ByVal point As Point, ByVal line As Point()) As Double
            Return Math.Sqrt((Math.Pow(CDbl(Math.Abs(CInt((((point.Y - line(0).Y) * (line(1).X - line(0).X)) - ((point.X - line(0).X) * (line(1).Y - line(0).Y)))))), 2) / (Math.Pow(CDbl((line(1).X - line(0).X)), 2) + Math.Pow(CDbl((line(1).Y - line(0).Y)), 2))))
        End Function

        Friend Shared Function DistanceFromPointToRectangle(ByVal point As Point, ByVal rect As Rectangle) As Double
            Dim list As New List([Of] Double) { DesignerGeometryHelper.DistanceBetweenPoints(point, New Point(rect.Left, rect.Top)), DesignerGeometryHelper.DistanceBetweenPoints(point, New Point((rect.Left + (rect.Width / 2)), rect.Top)), DesignerGeometryHelper.DistanceBetweenPoints(point, New Point(rect.Right, rect.Top)), DesignerGeometryHelper.DistanceBetweenPoints(point, New Point(rect.Right, (rect.Top + (rect.Height / 2)))), DesignerGeometryHelper.DistanceBetweenPoints(point, New Point(rect.Right, rect.Bottom)), DesignerGeometryHelper.DistanceBetweenPoints(point, New Point((rect.Right + (rect.Width / 2)), rect.Bottom)), DesignerGeometryHelper.DistanceBetweenPoints(point, New Point(rect.Left, rect.Bottom)), DesignerGeometryHelper.DistanceBetweenPoints(point, New Point(rect.Left, (rect.Bottom - (rect.Height / 2)))) }
            Dim num As Double = list.Item(0)
            Dim i As Integer
            For i = 1 To list.Count - 1
                num = Math.Min(num, list.Item(i))
            Next i
            Return num
        End Function

        Friend Shared Function DistanceOfLineSegments(ByVal segments As Point()) As Double
            Dim num As Double = 0
            Dim i As Integer
            For i = 1 To segments.Length - 1
                num = (num + DesignerGeometryHelper.DistanceBetweenPoints(segments((i - 1)), segments(i)))
            Next i
            Return num
        End Function

        Friend Shared Function MidPointOfLineSegment(ByVal point1 As Point, ByVal point2 As Point) As Point
            Return New Point(((point1.X + point2.X) / 2), ((point1.Y + point2.Y) / 2))
        End Function

        Friend Shared Function PointOnLineSegment(ByVal point As Point, ByVal line As Point(), ByVal hitAreaSize As Size) As Boolean
            Dim rectangle As Rectangle = DesignerGeometryHelper.RectangleFromLineSegments(line)
            rectangle.Inflate(hitAreaSize)
            If rectangle.Contains(point) Then
                Dim num As Double = DesignerGeometryHelper.DistanceFromPointToLineSegment(point, line)
                If ((num < hitAreaSize.Width) AndAlso (num < hitAreaSize.Height)) Then
                    Return True
                End If
            End If
            Return False
        End Function

        Friend Shared Function RectangleFromLineSegments(ByVal segments As Point()) As Rectangle
            If (segments.Length = 0) Then
                Return Rectangle.Empty
            End If
            Dim location As Point = segments(0)
            Dim point2 As Point = segments(0)
            Dim point3 As Point
            For Each point3 In segments
                location.X = Math.Min(location.X, point3.X)
                location.Y = Math.Min(location.Y, point3.Y)
                point2.X = Math.Max(point2.X, point3.X)
                point2.Y = Math.Max(point2.Y, point3.Y)
            Next
            Dim rectangle As New Rectangle(location, New Size((point2.X - location.X), (point2.Y - location.Y)))
            rectangle.Inflate(4, 4)
            Return rectangle
        End Function

        Friend Shared Function SlopeOfLineSegment(ByVal start As Point, ByVal [end] As Point) As Single
            If (start.X = [end].X) Then
                Return Single.MaxValue
            End If
            If (start.Y = [end].Y) Then
                Return 0!
            End If
            Return (CSng(([end].Y - start.Y)) / CSng(([end].X - start.X)))
        End Function

    End Class
End Namespace

